package com.wugh.fast.generator;


import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.dom.java.CompilationUnit;
import org.mybatis.generator.api.dom.java.Field;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import tk.mybatis.mapper.generator.MapperCommentGenerator;

import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author WUGH
 * @date 2018/7/25
 */
public class FastCommentGenerator extends MapperCommentGenerator {
    //数建的sqlite数据库
    private boolean isSjkjSqlite = false;

    private String deleteColumnName;
    private AnnotationParser isDeletedAnnotation;
    private AnnotationParser keySqlAnnotation;
    private List<String> skipInsertColumnNames;
    private List<String> skipUpdateColumnNames;

    @Override
    public void addJavaFileComment(CompilationUnit compilationUnit) {
        super.addJavaFileComment(compilationUnit);
    }

    @Override
    public void addConfigurationProperties(Properties properties) {
        super.addConfigurationProperties(properties);
        String isSjkjSqlite = properties.getProperty("isSjkjSqlite");
        if (StringUtils.equalsIgnoreCase(isSjkjSqlite, "true")) {
            this.isSjkjSqlite = true;
        }
        String deleteColumnName = properties.getProperty("deleteColumnName");
        if (StringUtils.isNotBlank(deleteColumnName)) {
            this.deleteColumnName = deleteColumnName;
        }
        String isDeletedAnnotation = properties.getProperty("isDeletedAnnotation");
        if (StringUtils.isNotBlank(isDeletedAnnotation)) {
            this.isDeletedAnnotation = new AnnotationParser(isDeletedAnnotation);
        }
        String keySqlAnnotation = properties.getProperty("keySqlAnnotation");
        if (StringUtils.isNotBlank(keySqlAnnotation)) {
            this.keySqlAnnotation = new AnnotationParser(keySqlAnnotation);
        }
        String skipInsertColumnNames = properties.getProperty("skipInsertColumnNames");
        if (StringUtils.isNotBlank(skipInsertColumnNames)) {
            this.skipInsertColumnNames = Arrays.asList(skipInsertColumnNames.split(","));
        }
        String skipUpdateColumnNames = properties.getProperty("skipUpdateColumnNames");
        if (StringUtils.isNotBlank(skipUpdateColumnNames)) {
            this.skipUpdateColumnNames = Arrays.asList(skipUpdateColumnNames.split(","));
        }
    }

    @Override
    public void addFieldComment(Field field, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) {
        //前处理属性名,再执行后续操作
        if (isSjkjSqlite) {
            field.setName(SQLiteUtil.handleName(introspectedColumn.getActualColumnName()));
        }
        super.addFieldComment(field, introspectedTable, introspectedColumn);
        if (StringUtils.isNotBlank(deleteColumnName) && isDeletedAnnotation != null) {
            //添加注解和导包
            if (introspectedColumn.getActualColumnName().equalsIgnoreCase(deleteColumnName)) {
                field.addAnnotation(isDeletedAnnotation.getAnnotation());
            }
        }
        if (keySqlAnnotation != null && !introspectedColumn.isAutoIncrement()) {
            Set<String> pks = introspectedTable.getPrimaryKeyColumns().stream().map(IntrospectedColumn::getActualColumnName).collect(Collectors.toSet());
            if (pks.contains(introspectedColumn.getActualColumnName()) || introspectedColumn.isIdentity()) {
                field.addAnnotation(keySqlAnnotation.getAnnotation());
            }
        }
        if (CollectionUtils.isNotEmpty(skipInsertColumnNames) && skipInsertColumnNames.contains(introspectedColumn.getActualColumnName())) {
            List<String> annotations = field.getAnnotations();
            //字段注解
            String columnAnnotation = annotations.stream().filter(annotation -> annotation.startsWith("@Column(")).findFirst().orElse("@Column()");
            annotations.remove(columnAnnotation);
            annotations.add(StringUtils.replaceFirst(columnAnnotation, "\\)$", ", insertable=false\\)"));
        }
        if (CollectionUtils.isNotEmpty(skipUpdateColumnNames) && skipUpdateColumnNames.contains(introspectedColumn.getActualColumnName())) {
            List<String> annotations = field.getAnnotations();
            //字段注解
            String columnAnnotation = annotations.stream().filter(annotation -> annotation.startsWith("@Column(")).findFirst().orElse("@Column()");
            annotations.remove(columnAnnotation);
            annotations.add(StringUtils.replaceFirst(columnAnnotation, "\\)$", ", updatable=false\\)"));
        }
    }
}
